package com.leve.admin.repository;

import com.leve.admin.common.DateUtils;
import com.leve.admin.domain.Ghost;
import com.leve.admin.domain.GhostFriend;
import com.leve.admin.domain.GhostGreeting;
import com.mongodb.DBRef;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import static java.util.Arrays.asList;
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;

@Repository
public class GhostRepository {
    /**
     * mongodb space库
     * ghost - leve
     * comment、post - space
     */
    @Resource
    @Qualifier("cloudfsTemplate")
    private MongoOperations spaceMongoOperations;

    @Resource
    @Qualifier("mongoTemplate")
    private MongoOperations leveMongoOperations;

    @Resource
    @Qualifier("landTemplate")
    private MongoOperations landMongoOperations;


    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd ");

    public Document selectOneByGhostGreet(String gid) {
        Query query = Query.query(Criteria.where("status").is("ACCEPTED").and("receiver").is(new DBRef("ghost", new ObjectId(gid))));
        return landMongoOperations.findOne(query, Document.class, "ghostGreeting");
    }

    public List<Ghost> selectBySex(String sex) {
        Query query = Query.query(Criteria.where("virtual").is(true).and("gender").is(sex));
        return landMongoOperations.find(query, Ghost.class, "ghost");

    }

    public Document findGhostByAccid(String accid) {
        Query query = Query.query(Criteria.where("im_id").is(accid));
        return landMongoOperations.findOne(query, Document.class, "ghost");
    }

    public List<Document> selectByUid(String uid) {
        Query query = Query.query(Criteria.where("user_id").is(uid));
        return spaceMongoOperations.find(query, Document.class, "post");
    }

    public List<Ghost> ghosts(PageRequest pageRequest, String name, String statusId) {
        Criteria criteria = Criteria.where("virtual").is(false);
        criteria.and("enabled").is(true);//真实用户
        if (name != null && name.length() > 0) {
            Pattern pattern = Pattern.compile("^.*" + name + ".*$", Pattern.CASE_INSENSITIVE);
            criteria.and("nickname").regex(pattern);
        }
        if (statusId != null && statusId.length() > 0) {
            criteria.and("gender").is(statusId);
        }
        return landMongoOperations.find(Query.query(criteria).with(new Sort(Sort.Direction.DESC, "created_date")).with(pageRequest), Ghost.class, "ghost");
    }

    public Ghost selectOneByGost(String gid) {
        Query query = Query.query(Criteria.where("id").is(new ObjectId(gid)));
        return landMongoOperations.findOne(query, Ghost.class, "ghost");
    }

    public List<Ghost> getservers() {
        Query query = Query.query(Criteria.where("virtual").is(true));
        return landMongoOperations.find(query, Ghost.class, "ghost");

    }

    /**
     * 查询好友数
     *
     * @param ghostId
     * @return
     */
    public List<GhostFriend> findGhostFriends(String ghostId) {
        return landMongoOperations.find(
                query(new Criteria()
                        .andOperator(
                                where("owner.$id").is(new ObjectId(ghostId)),
                                where("imGroupId").exists(true))
                ),
                GhostFriend.class);
    }

    /**
     * 查询 打招呼数
     *
     * @param ghostId
     * @return
     */
    public List<GhostGreeting> findGreetings(String ghostId) {
        return landMongoOperations.find(
                query(new Criteria()
                        .orOperator(
                                where("sender.$id").is(new ObjectId(ghostId))
                                        .andOperator(where("access").in(asList("ALL", "SENDER"))),
                                where("receiver.$id").is(new ObjectId(ghostId))
                                        .andOperator(where("access").in(asList("ALL", "RECEIVER"))))
                ).with(new Sort(Sort.Direction.DESC, "createdDate")),
                GhostGreeting.class);
    }

    /*  */

    /**
     * 根据指定时间范围查询注册用户
     */
    public List<Ghost> findGhostByCreateDate(int day, String gender) {
        Date startDate = DateUtils.startDate(day);
        Date endDate = DateUtils.endDate(0);
        Query query;
        if (gender == null) {
            query = Query.query(Criteria.where("created_date").gte(startDate).lte(endDate));
        } else {
            query = Query.query(Criteria.where("created_date").gte(startDate).lte(endDate).and("gender").is(gender));
        }
        return landMongoOperations.find(query, Ghost.class, "ghost");
    }


    /**
     * 根据指定时间范围查询注册用户
     */
    public Map findGhostCountByCreateDate(int day, String gender) {
        Date startDate = DateUtils.startDate(day);
        Date endDate = DateUtils.endDate(0);
        Criteria criteria = new Criteria();
        criteria.and("enabled").is(true);
        if (gender == null) {
            criteria.and("created_date").gte(startDate).lte(endDate);
        } else {
            criteria.and("created_date").gte(startDate).lte(endDate).and("gender").is(gender);
        }
        Aggregation agg = Aggregation.newAggregation(Aggregation.match(criteria),//查询条件
                Aggregation.group("enabled").count().as("totalCount"));
        return landMongoOperations.aggregate(agg, "ghost", Map.class).getUniqueMappedResult();

    }


    /*    */

    /**
     * 根据指定时间范围查询登陆过的用户
     */
    public List<Ghost> findGhostBylastDate(int day, String gender) {
        Date startDate = DateUtils.startDate(day);
        Date endDate = DateUtils.endDate(0);
        Query query;
        if (gender == null) {
            query = Query.query(Criteria.where("last_modified_date").gte(startDate).lte(endDate));
        } else {
            query = Query.query(Criteria.where("last_modified_date").gte(startDate).lte(endDate).and("gender").is(gender));
        }
        return landMongoOperations.find(query, Ghost.class, "ghost");
    }


    /**
     * 根据指定时间范围查询登陆过的用户
     */
    public Map findGhostCountBylastDate(int day, String gender) {
        Date startDate = DateUtils.startDate(day);
        Date endDate = DateUtils.endDate(0);
        Criteria criteria = new Criteria();
        criteria.and("enabled").is(true);
        if (gender == null) {
            criteria.and("last_modified_date").gte(startDate).lte(endDate);
        } else {
            criteria.and("last_modified_date").gte(startDate).lte(endDate).and("gender").is(gender);
        }
        Aggregation agg = Aggregation.newAggregation(Aggregation.match(criteria),//查询条件
                Aggregation.group("enabled").count().as("totalCount"));
        return landMongoOperations.aggregate(agg, "ghost", Map.class).getUniqueMappedResult();


    }

    //


    /**
     * 根据指定时间范围查询登陆过的用户
     */
    public List<Ghost> findGhostBylastDate(int day, String gender, PageRequest pageRequest) {
        Date startDate = DateUtils.startDate(day);
        Date endDate = DateUtils.endDate(0);
        Query query;
        if (gender == null) {
            query = Query.query(Criteria.where("last_modified_date").gte(startDate).lte(endDate));
        } else {
            query = Query.query(Criteria.where("last_modified_date").gte(startDate).lte(endDate).and("gender").is(gender));
        }
        return landMongoOperations.find(query.with(new Sort(Sort.Direction.DESC, "created_date")).with(pageRequest), Ghost.class, "ghost");
    }


    /**
     * 根据指定时间范围查询注册用户
     */
    public List<Ghost> findGhostByCreateDate(int day, String gender, PageRequest pageRequest) {
        Date startDate = DateUtils.startDate(day);
        Date endDate = DateUtils.endDate(0);
        Query query;
        if (gender == null) {
            query = Query.query(Criteria.where("created_date").gte(startDate).lte(endDate));
        } else {
            query = Query.query(Criteria.where("created_date").gte(startDate).lte(endDate).and("gender").is(gender));
        }
        return landMongoOperations.find(query.with(new Sort(Sort.Direction.DESC, "created_date")).with(pageRequest), Ghost.class, "ghost");
    }
}
